L.UserList = L.Class.extend({
	includes : L.Mixin.Events,

	initialize : function(couplingOptions) {
		var self = this;
		this._users = [];
		this._requesters = [];
		
		if ( couplingOptions && couplingOptions.enabled )
			this._couple(couplingOptions);
	    
		setTimeout(function() { self.fire('ready', null); }, Skt.config.TIME_TO_READY);
	},

	addUser : function(id, name, lastname, rol) {
		
		if ( !this._userIsRegistered(id) ) {
			var user = {
				id : id,
				name : name,
				lastname: lastname,
				rol : rol,
				instances : 0
			};
	
			this._users.push(user);
	
			this.fire('userAction', {
				action_name : 'addUser',
				attr_list : {
					userId : id
				}
			});
		}

	},

	removeUser : function(id) {

		if ( this._userIsRegistered(id) ) {
		
			var index = this._findIndex(id);
			this._users.splice(index, 1);
	
			this.fire('userAction', {
				action_name : 'removeUser',
				attr_list : {
					userId : id
				}
			});
			
		}
	},

	changeInstances : function(id, addValue) {
		var user = this.getUser(id);
		if ( user != null ) {
			user.instances = user.instances + addValue;
			
			this.fire('userAction', {
				action_name : 'changeInstances',
				attr_list : {
					userId : id,
					addValue : addValue
				}
			});
		}
	},
	
	issueRequest: function(userId) {
		if ( !this.isRequester(userId) ) {
			this._requesters.push(Number(userId));
			this.fire("requestIssued", {
				userId: userId
			});
		}
	},
	
	dismissRequest: function(userId) {
		if ( this.isRequester(userId) ) {
			this._requesters.splice(this._requesters.indexOf(Number(userId)), 1);
			this.fire('requestDismissed', {
				userId: userId
			});
		}
	},
	
	isRequester: function(userId) {
		return $.inArray(Number(userId), this._requesters) >= 0;
	},
	
	requestersEmpty: function() {
		return this._requesters.length <= 0;
	},
	
	getRequesters: function() {
		return this._requesters;
	},

	eachUser : function(fn, context) {
		var users = this._users;
		for ( var i = 0, n = users.length; i < n; i++) {
			fn.call(context, users[i]);
		}
	},

	_findIndex : function(id) {
		var users = this._users;
		for ( var i = 0, n = users.length; i < n; i++) {
			if (users[i].id == id)
				return i;
		}
		return -1;
	},
	
	userIsOnline: function(userId) {
		var user = this.getUser(userId);
		if ( user != null )
			return user.instances > 0;
		return false;
	},
	
	_userIsRegistered: function(userId) {
		return this._findIndex(userId) >= 0;
	},

	getUser : function(id) {
		var index = this._findIndex(id);
		if ( index < 0 )
			index = this._findIndex(Number(id));
		if ( index < 0 )
			index = this._findIndex(String(id));
		if ( index != -1 )
			return this._users[index];
		return null;
	},

	getUsers : function() {
		return this._users;
	},

	getCount : function() {
		return this._users.length;
	},

	_clearObject : function() {
		this._users = [];
	},
	getState:function(){
		var state={
				users:this._users,
				requesters:this._requesters
		};
		return state;
	},
	setState:function(state){
		var newUserIds={};
		var newRequesterIds={};
		var users=[];
		var idsToDelete=[];
		var requesters=[];
	
		//add and update new users
		for(var i=0;i<state.users.length;i=i+1){
			this.addUser(state.users[i].id, state.users[i].name, state.users[i].lastname, state.users[i].rol);
			var user = this.getUser(state.users[i].id);
			newUserIds[user.id]=true;
			if(state.users[i].instances!= user.instances){
				this.changeInstances(user.id,state.users[i].instances-user.instances);
			}
		}
		//remove disconected users
		users=this.getUsers();
		for(var i=0;i<users.length;i=i+1){
			if(!newUserIds[users[i].id]){
				idsToDelete.push(users[i].id);
			}
		}
		for(var i=0;i<idsToDelete.length;i=i+1){
			this.removeUser(idsToDelete[i]);
		}
		//new requesters
		for(var i=0;i<state.requesters.length;i=i+1){
			this.issueRequest(state.requester[i]);
			newRequesterIds[state.requester[i]]=true;
		}
		//remove requester
		requesters=this.getRequesters();
		idsToDelete=[];
		for(var i=0;i<requesters.length;i=i+1){
			if(!newRequesterIds[requesters[i]]){
				idsToDelete.push(requesters[i]);
			}
		}
		for(var i=0;i<idsToDelete.length;i=i+1){
			this.dismissRequest(idsToDelete[i]);
		}
		
		
	},
	
	_couple: function(couplingOptions) {
		couplingOptions.adapter.coupleObject(
			couplingOptions.carriedId,
			this,
			{
				messageType: "STATE",
				explicitMapping: ["addUser", "removeUser", "changeInstances", "issueRequest", "dismissRequest"]
			}
		);
	}

});
